package com.xxgc.demo.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xxgc.demo.controller.pojo.SeatPOJO;
import com.xxgc.demo.controller.result.Result;
import com.xxgc.demo.entity.DemoUsers;
import com.xxgc.demo.service.IDemoUsersService;
import com.xxgc.demo.utils.RedisUtil;
import com.xxgc.demo.utils.SeatUtil;
import com.xxgc.demo.utils.SpeechSynthesisUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Tag(name = "整合Redis")
@RestController
@RequestMapping("/redis")
public class UserRedisController {

    @Autowired
    private IDemoUsersService iDemoUsersService;

    @Autowired
    private RedisUtil redisUtil;

    @Operation(summary = "通过手机号查询用户",description = "手机号查询")
    @GetMapping("/selectUserByPhone")
    public Result selectUserByPhone(String phone){
        //得到一个key
        String key = "selectUserByPhone_"+phone;
        //先查缓存
        if(redisUtil.hasKey(key)){
            log.info("走缓存");
            List<DemoUsers> list = (List<DemoUsers>) redisUtil.get(key);
            return Result.ok(list);
        }else {
            log.info("走数据库");
            //缓存里面没有
            QueryWrapper<DemoUsers> qw = new QueryWrapper<>();
            qw.eq("phone",phone);
            List<DemoUsers> list = iDemoUsersService.list(qw);
            //在缓存中保留一份
            redisUtil.set(key,list,60 * 60 * 12);
            return Result.ok(list);
        }
    }

    @Operation(summary = "通过电话修改用户",description = "修改用户")
    @PostMapping("/updateUserNameByPhone")
    public Result updateUserNameByPhone(String phone,String name){
        UpdateWrapper<DemoUsers> qw = new UpdateWrapper<>();
        qw.eq("phone",phone);
        qw.set("name",name);
        iDemoUsersService.update(qw);
        //得到一个key
        String key = "selectUserByPhone_"+phone;
        //删除对应缓存
        redisUtil.del(key);
        return  Result.ok();
    }

    @Operation(summary = "通过邮箱获取验证码",description = "获取验证码")
    @GetMapping("/getCodeByEmail")
    public Result getCodeByEmail(String email){
        //生成一个key
        String key = "email_"+email;
        //验证code是否存在或者是否过期
        if(redisUtil.hasKey(key)){
            long expire = redisUtil.getExpire(key);
            return Result.error().msg("请"+expire+"s之后重新获取验证码");
        }
        //生成6位数的验证码
        String code = RandomUtil.randomNumbers(6);
        //给用户的邮箱发送验证码
        MailUtil.send(email, "91打卡系统注册", "请不要将注册码告诉其他人。注册码: "+code+"。请在1分钟之内完成注册，91系统欢迎您。", false);
        //缓存中保存code
        redisUtil.set(key,code,60);
        log.info("code:"+code);
        return Result.ok();
    }

    @Operation(summary = "用户注册邮箱",description = "用户注册")
    @PostMapping("/addUserByEmailAndCode")
    public Result addUserByEmailAndCode(String email,String code){
        String key = "email_"+email;
        //验证code是否存在 或者是否过期
        if(redisUtil.hasKey(key)){
            String codeRedis = (String)redisUtil.get(key);
            if(codeRedis.equals(code)){
                redisUtil.del(key);
                return Result.ok().msg(email+"注册成功");
            }
        }
        return Result.error().msg("注册码过期请重新发送");
    }

    //写一个美团叫号功能
    //需求：取号 过号 叫号
    //取号：自动排队，但不能大于100桌
    //过号：过号可以重排，重排顺延3桌，但大于10桌后不允许重排
    //叫号：叫号播放3次，在或不在都移除当前号
    @Operation(summary = "美团取号",description = "取号")
    @GetMapping("/getNumber")
    public Result getNumber(Integer seatType){
        //当前是第几号
        //给number递增1 如果没有就新建
        redisUtil.incr("number",1);
        //获取最新的是第几号
        Integer number = (Integer) redisUtil.get("number");
        String seatName = SeatUtil.getSeatName(number, seatType);
        SeatPOJO seatPOJO = new SeatPOJO(number,seatName,seatType,new Date());
        //list集合
        List<SeatPOJO> list = null;
        if(redisUtil.hasKey("line_up")){
            list = (List<SeatPOJO>)redisUtil.get("line_up");
        }else {
            list = new ArrayList<>();
        }
        list.add(seatPOJO);
        //能不能把list丢redis
        redisUtil.set("line_up",list);
        return Result.ok(seatName);
    }

    @Operation(summary = "美团叫号",description = "叫号")
    @GetMapping("/callNumber")
    public Result callNumber(Integer seatType){
        List<SeatPOJO> list = (List<SeatPOJO>) redisUtil.get("line_up");
        //循环这个排队的对象 iter
        for (SeatPOJO seatPOJO : list) {
            if(seatPOJO.isCall()){
                //如果是已叫过的号就结束本次循环
                continue;
            }
            //判断桌子的类型是否一致
            if(seatPOJO.getSeatType() == seatType){
                if(seatPOJO.getWaiting() == 0){
                    String msg = seatPOJO.getSeatName() + "请您用餐啦!";
                    //移除
                    seatPOJO.setCall(true);
                    seatPOJO.setCallTime(new Date());
                    redisUtil.set("line_up",list);

                    //调用语音工具类
                    SpeechSynthesisUtil ttsTool = new SpeechSynthesisUtil("0adfa098");
                    ttsTool.textToVoice(msg+"。。"+msg+"。。"+msg);

                    return Result.ok(msg);
                }else{
                    seatPOJO.setWaiting(seatPOJO.getWaiting() - 1);
                }
            }
        }
        return Result.ok("当前桌子类型没有排队，可以直接用餐");
    }

    @Operation(summary = "美团过号",description = "过号")
    @GetMapping("/callStation")
    public Result callStation(Integer seatType,Integer number){
        List<SeatPOJO> list = (List<SeatPOJO>)redisUtil.get("line_up");
        //循环这个排队的对象
        for (SeatPOJO seatPOJO : list) {
            if (seatPOJO.getSeatNum() == number){
                seatPOJO.setCall(false);
                seatPOJO.setWaiting(3);
                redisUtil.set("line_up",list);
                break;
            }
        }
        return Result.ok("3桌后叫您");
    }

    @Operation(summary = "test",description = "test")
    @GetMapping("/redisTest")
    public Result redisTest(){
        redisUtil.set("name","myz",20);
        return Result.ok("myz来咯");
    }

    @Operation(summary = "testGet",description = "testGet")
    @GetMapping("/redisTestGet")
    public Result redisTestGet(){
        Object name = redisUtil.get("name");
        return Result.ok("myz来咯").data(String.valueOf(name));
    }
}
